package stream;

import lombok.Data;
import org.junit.Test;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public class UseCollectorsToMap {

    /**
     *
     * 测试使用stream 的 toMap 方法将list->map
     *
     * 1.在使用 java.util.stream.Collectors 类的 toMap()方法转为 Map 集合时，一定要使
     * 用含有参数类型为 BinaryOperator，参数名为 mergeFunction 的方法，否则当出现相同 key
     * 值时会抛出 IllegalStateException 异常
     * 说明：参数 mergeFunction 的作用是当出现 key 重复时，自定义对 value 的处理策略。
     *
     * 2.在使用 java.util.stream.Collectors 类的 toMap()方法转为 Map 集合时，一定要注
     * 意当 value 为 null 时会抛 NPE 异常。
     *
     * @param args
     */
    public static void main(String[] args) throws Exception {
        List<Pair<String, Double>> pairArrayList = new ArrayList<>(3);
        String data1String = "2021-12-12 10:00:00";
        String data2String = "2022-12-12 10:00:00";
        String data3String = "2023-12-12 10:00:00";

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date data1 = simpleDateFormat.parse(data1String);
        Date data2 = simpleDateFormat.parse(data2String);
        Date data3 = simpleDateFormat.parse(data3String);


        //pairArrayList.add(new Pair<>("version", null)); value为空时会抛异常
        pairArrayList.add(new Pair<>("version1", 10.14, data1));
        pairArrayList.add(new Pair<>("version1", 10.24, data3));
        pairArrayList.add(new Pair<>("version1", 10.34, data2));
        pairArrayList.add(new Pair<>("version2", 15.38, new Date()));


        Map<String, Pair<String, Double>> collect = pairArrayList.stream().collect(Collectors.toMap(Pair::getKey, e -> e, (o1, o2) -> o1));



        Map<String, Pair<String, Double>> result = pairArrayList.stream().collect(Collectors.toMap(Pair::getKey, pair -> pair, (o1, o2) -> o1.getDate().compareTo(o2.getDate()) > 0 ? o1:o2));
        for (Map.Entry<String, Pair<String, Double>> entry : result.entrySet()) {
            System.out.println(entry.getKey());
            System.out.println(entry.getValue().toString());
        }
    }

    @Test
    public void test01(){
        List<String> list = new ArrayList<>(Arrays.asList("a", "b"));
        List<String> result = new ArrayList<>(list);
        list.add("c");
        System.out.println(result);
    }

    @Test
    public void test02(){
        List<Pair<String, BigDecimal>> pairArrayList = new ArrayList<>(4);
        pairArrayList.add(new Pair<>("version1", BigDecimal.valueOf(10.14), null));
        pairArrayList.add(new Pair<>("version1", BigDecimal.valueOf(10.24), null));
        pairArrayList.add(new Pair<>("version1", BigDecimal.valueOf(10.34), null));
        pairArrayList.add(new Pair<>("version2", BigDecimal.valueOf(15.38), null));
        Map<String, Pair<String, BigDecimal>> collect = pairArrayList.stream().collect(Collectors.toMap(Pair::getKey, pair -> pair, (o1, o2) -> {
            o1.setValue(o1.getValue().add(o2.getValue()));
            return o1;
        }));
        for (Map.Entry<String, Pair<String, BigDecimal>> entry : collect.entrySet()) {
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
        }

    }
}

@Data
class Pair<K,V>{

    private K key;
    private V value;

    private Date date;

    public Pair(K k,V v, Date date){
        this.key = k;
        this.value = v;
        this.date = date;
    }

    public K getKey() {
        return key;
    }

    public void setKey(K key) {
        this.key = key;
    }

    public V getValue() {
        return value;
    }

    public void setValue(V value) {
        this.value = value;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

}